Message Blocks

IDL maintains messages in opaque data structures known as Message Blocks. A message block contains all the messages for a logically related area.

When IDL starts, there is only one defined block named IDL_MBLK_CORE, containing all messages defined by the core IDL product. Typically, dynamically loadable modules (DLMs) each define a message block for their error messages when they are loaded (See Dynamically Loadable Modules for a description of DLMs).

There are often two versions of IDL message module functions. Those with names that end in FromBlock require an explicit message block. The versions that do not end in FromBlock use the IDL_MBLK_CORE message block.

Define a Message Block

To define a message block, you must supply an array of IDL_MSG_DEF structures:

typedef struct {

   char *name;

   char *format;

} IDL_MSG_DEF;

where:

name

A string giving the name of the message. We suggest that you adopt a consistent unique prefix for all your error codes. All predefined IDL message codes start with the prefix IDL_M_. Do not use this prefix when naming your blocks in order to avoid unnecessary name collisions.

format

A format string, in printf(3) format. There is one extension to the printf formatting codes: If the first two letters of the format are “%N”, then IDL will substitute the name of the currently executing IDL procedure or function (if any) followed by a colon and a space when this message is issued. For example:

IDL> print, undefined_var

% PRINT: Variable is undefined: UNDEFINED_VAR.

IDL_MessageDefineBlock()

The IDL_MessageDefineBlock() function is used to define a new message block:

IDL_MSG_BLOCK IDL_MessageDefineBlock

(char *block_name, int n, IDL_MSG_DEF *defs)

Arguments

block_name

Name of the message block. This can be any string, but it will be case folded to upper case. We suggest a single word be used. It is important to pick names that are unlikely to be used by any other application. All blocks defined by NV5 Geospatial Solutions start with the prefix IDL_MBLK_. Do not use this prefix when naming your blocks in order to avoid unnecessary confusion.

n

Number of message definitions pointed at by defs.

defs

An array of message definition structs, each one supplying the name and format string for a message in printf(3) format. The memory used for this array, including the strings it points at, must be in permanently allocated read-only storage. IDL does not copy this memory, but uses it in place.

If possible, the new message block is defined and an opaque pointer to it is returned. This pointer must be supplied to subsequent calls to the “FromBlock” message module functions to identify the message block a given error is being issued from. If it is not possible to define the message block, this function returns NULL.

The message functions require a message block pointer and the negative index of the specific message to be issued. Hence, message codes start and zero and grow negatively. For mnemonic convenience, it is standard practice to define preprocessor macros to represent the error codes.

Example: Defining A Message Block

The following code defines a message block named TESTMODULE that contains two messages:

static IDL_MSG_DEF msg_arr[] =

{

   #define M_TM_INPRO 0

   { "M_TM_INPRO", "%NThis is from a loadable module procedure."

   },

   #define M_TM_INFUN -1

   { "M_TM_INFUN", "%NThis is from a loadable module function."

   },

};

 

msg_Block = IDL_MessageDefineBlock("TestModule", $

   sizeof(rosg_arr)/sizeof(rosg_arr[O]), $

   rosg_arr);